#include "EventList.h"
#include "EventString.h"

#include <stdio.h>
#include <stdlib.h>

typedef struct _TestS
{
	euint32	     num1;
	EventString *string;
	efloat64     f1;
} TestS;

static TestS *
create_test(euint32 num1, const char *str, efloat64 f1)
{
	TestS *t  = MALLOC_NEW(TestS);
	t->num1	  = num1;
	t->string = event_string_new(str);
	t->f1	  = f1;

	return t;
}

static void
delete_test(TestS *t)
{
	return_if_fail(t != NULL, delete);
	event_object_unref(t->string);
	free(t);
}

static void
print_test(TestS *t)
{
	if (!t)
		printf("NULL of TestS* !\n");
	printf("TestS:\nnum1<%u>,\nstring<%s>,\nf1<%lf>\n", t->num1,
	       event_string_get_string(t->string), t->f1);
}

static EventList *
test_to_list(TestS *t)
{
	EventList *head;

	head = event_list_new();
	event_list_add_data(head, EPTR(*((euint64 *)(&t->num1))),
			    EVENT_TYPE_UINT32, NULL);
	event_list_add_data(head, EPTR(t->string), EVENT_TYPE_STRING,
			    event_object_unref);
	event_list_add_data(head, EPTR(*((euint64 *)(&t->f1))),
			    EVENT_TYPE_FLOAT64, NULL);
	event_list_refresh(head);

	return head;
}

static TestS *
list_to_test(EventList *list)
{
	TestS	    *t;
	EventString *str  = NULL;
	EventNode   *node = EVENT_NODE(list);
	euint32	     num  = 0;
	efloat64     f	  = 0.0;

	return_val_if_fail(list != NULL, list_to_test, NULL);

	num  = *((euint32 *)(&node->data));
	node = node->next;
	if (!node)
		goto make_pack;
	str  = EVENT_STRING(node->data);
	node = node->next;
	if (!node)
		goto make_pack;
	f = *((efloat64 *)(&node->data));

make_pack:
	t = create_test(num, (str ? event_string_get_string(str) : "NULL"), f);
	return t;
}

int
main(int argc, char **argv)
{
	TestS	  *t1 = NULL, *t2 = NULL;
	EventList *l1 = NULL, *l2 = NULL;
	EventRaw  *raw = NULL;

	t1 = create_test(12345, "test of string", 666.33);
	print_test(t1);

	l1 = test_to_list(t1);

	raw = event_list_export_raw(l1);

	if (!raw) {
		printf("E: 序列化失败！\n");
		goto err_exit;
	}

	l2 = event_list_new_with_raw(event_raw_get_data(raw));

	if (!l2) {
		printf("E: 反序列化失败！\n");
		goto err_exit;
	}

	t2 = list_to_test(l2);
	print_test(t2);

err_exit:
	delete_test(t1);
	delete_test(t2);
	event_object_unref(l1);
	event_object_unref(l2);
	event_object_unref(raw);
	return 0;
}
